<?php
include_once "common_functions.php";
function fork()
{
    global $childs;
    $pid = pcntl_fork();
    if ($pid < 0) die("fork err");
    if ($pid == 0) {
        $child_pid = posix_getpid();
        while (true) {
            sleep(10);
        }

    } else {
        $parent_pid = posix_getpid();
        $childs[$pid] = $pid;
    }
}

function waiting()
{
    global $childs, $worker_num;
    while (count($childs)) {
        if (($exit_id = pcntl_wait($status)) > 0) {
            $signo = pcntl_wtermsig($status);
            unset($childs[$exit_id]);
            file_put_contents("./log", $exit_id . ' exit' . PHP_EOL, FILE_APPEND);
        }
        if (count($childs) < $worker_num) {
            file_put_contents("./log", 'will fork' . PHP_EOL, FILE_APPEND);
            fork();
        }
    }
}

//验证是否存而且合法
function getPidFile()
{
    if (file_exists(PID_FILE)) {
        $master_pid = file_get_contents(PID_FILE);
        if ($master_pid) {
            return $master_pid;
        }
    }
    return false;

}


define('PID_FILE', "/var/run/master.pid");
$childs = [];
$worker_num = 5;
echo '###' . posix_getpid() . '###' . PHP_EOL;
$cmd = $argv[1] ?? '';
switch ($cmd) {
    case 'start':
        if (getPidFile()) {
            die("Already runing! " . PID_FILE . PHP_EOL);
        }
        daemon();
        $master_pid = posix_getpid();
        file_put_contents(PID_FILE, $master_pid);
        for ($i = 0; $i < $worker_num; $i++) {
            fork();
        }
        waiting();
        break;
    case 'reload':
        $master_pid = getPidFile();
        if (!$master_pid) {
            die(PID_FILE . " invalid");
        }
        exec("ps --ppid {$master_pid}|awk '/[0-9]/{print $1}'|xargs", $output, $status);
        if ($status == 0) {
            $child_arr = explode(' ', current($output));
            foreach ($child_arr as $id) {
                posix_kill($id, SIGTERM);
            }
        }


        exit();
    case 'stop':
        $master_pid = getPidFile();
        if (!$master_pid) {
            die(PID_FILE . " invalid");
        }

        exec("ps --ppid {$master_pid}|awk '/[0-9]/{print $1}'|xargs", $output, $status);
        //先杀子进程，在杀的时候，master还在活着，这个时候master里的 pcntl_wait执行不到呢？sleep才行？ 在48行
        if ($status == 0) {
            $child_arr = array_filter(explode(' ', current($output)));
            foreach ($child_arr as $id) {
                if (posix_kill($id, SIGKILL)) {
//                    sleep(1);
                    echo 'child ' . $id . ' exit successfully!' . PHP_EOL;
                }
            }
        }

        if ($r = posix_kill($master_pid, SIGKILL)) {
            echo 'master ' . $master_pid . ' exit successfully!' . PHP_EOL;
            unlink(PID_FILE);
        } else {
            //查看进程是否在运行
            exec("ps --pid {$master_pid}|grep -v CMD|awk '{print $1}'", $output, $status);
            $get_master_id = current($output);
            if (!$get_master_id) {
                @unlink(PID_FILE);
            }
            echo 'master ' . $master_pid . ' exit Fail! deleted pid file' . var_export($r, true) . PHP_EOL;
        }
        exit();
    default:
        die ("please input command" . PHP_EOL);
}


